package net.onceface.application.impl;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import net.onceface.application.CategoryApplication;
import net.onceface.application.ProductApplication;
import net.onceface.application.assembler.ProductAssembler;
import net.onceface.application.dto.CategoryDTO;
import net.onceface.application.dto.ProductDTO;
import net.onceface.core.domain.Product;
import net.onceface.infra.querychannel.QueryChannelService;
import net.onceface.infra.spring.ioc.InstanceFactory;

import org.springframework.transaction.annotation.Transactional;

@Named
@Transactional
public class ProductApplicationImpl implements ProductApplication{

	@Inject
	CategoryApplication categoryApplication;
	
	private QueryChannelService queryChannel;
	
	private QueryChannelService getQueryChannelService() {
		if (queryChannel == null) {
			queryChannel = InstanceFactory.getInstance(
					QueryChannelService.class, "queryChannel");
		}
		return queryChannel;
	}
	
	@Override
	public ProductDTO getProductDetails(Long id) {
		StringBuilder jpql = new StringBuilder("SELECT new net.onceface.application.dto.ProductDTO(_product) FROM Product _product")
		.append(" WHERE _product.sale = true")
		.append(" AND _product.abolishDate > NOW()")
		.append(" AND _product.id = :id");
		return (ProductDTO) getQueryChannelService()
				.createJpqlQuery(jpql.toString())
				.addParameter("id", id).singleResult();
	}

	@Override
	public ProductDTO getProduct(Long id) {
		return ProductAssembler.toDTO(Product.get(Product.class, id));
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ProductDTO> queryProductByCategory(Long CategoryId) {
		StringBuilder jpql = new StringBuilder("SELECT new net.onceface.application.dto.ProductDTO(_product.id,_product.name,_product.price,_product.originalPrice,_product.specName,_product.picture,_product.stock) FROM Product _product")
		.append(" WHERE _product.sale = true")
		.append(" AND _product.abolishDate > NOW()")
		.append(" AND _product.category.id in (:id)");
		List<CategoryDTO> cateList = categoryApplication.findByParentId(CategoryId);
		List<Long> ids = new ArrayList<Long>();
		if(cateList != null && cateList.size() > 0){
			for(CategoryDTO c : cateList){
				ids.add(c.getId());
			}
		}else{
			ids.add(CategoryId);
		}
		return getQueryChannelService()
				.createJpqlQuery(jpql.toString())
				.addParameter("id", ids).list();
	}

}
